﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using StockSBIE;
using System.IO;
using HAP = HtmlAgilityPack;
using StockSBDetails.webutil;
using StockSBDetails.tse;
using System.Data.Common;

namespace StockSBDetails
{
    public partial class Form1 : Form
    {

        StockSBDetailManager sbDetailManager = new StockSBDetailManager();
        public Form1()
        {
            SQLFactory.setPlatform(SQLFactory.SQLType.sqlite);
            InitializeComponent();
        }

        List<StockSBDetailManager.SBRecordState> SBTasks = null;
        TSE_SB_Crawling sb_Crawling = new TSE_SB_Crawling();
        public void processSB()
        {
            DateTime d = StockDataManager.getMaxTradeDate();

            DateTime vd = d.AddHours(16);

            TimeSpan ts = DateTime.Now.Subtract(vd);
            if (ts.TotalSeconds < 0)
            {
                MessageBox.Show("還沒到下午四點,無法處理");
                return;
            }


            if (SBTasks == null)
                return;


            String ds = DateUtils.getPlanString(d);
            String path = "d:\\SBdata\\" + ds + "\\";
            Directory.CreateDirectory(path);


            foreach (StockSBDetailManager.SBRecordState sbTask in SBTasks)
            {
                if (sbTask.處理進度.Equals(StockSBDetailManager.SBTaskState.抓取中))
                {
                    //先回復
                    sbTask.處理進度 = StockSBDetailManager.SBTaskState.待處理;
                    StockSBDetailManager.updateTaskState(sbTask.taskId, sbTask.處理進度, DateTime.Now);
                }
            }

            DateTime preD = DateTime.Now;
            foreach (StockSBDetailManager.SBRecordState sbTask in SBTasks)
            {
                if (sbTask.成交股數 == 0)
                    sbTask.處理進度 = StockSBDetailManager.SBTaskState.無資料;

                if (sbTask.處理進度.Equals(StockSBDetailManager.SBTaskState.待處理))
                {
                    sbTask.處理進度 = StockSBDetailManager.SBTaskState.抓取中;
                    try
                    {
                        //先看看有沒有這個檔案
                        String fileName = path + sbTask.代號 + "_" + sbTask.taskId.ToString("B") + ".sb";
                        if (File.Exists(fileName))
                        {
                            sbTask.處理進度 = StockSBDetailManager.SBTaskState.已抓取;
                        }
                        else
                        {
                            SBRecords records = sb_Crawling.CrawlingSB(sbTask.代號, d, sbTask.交易筆數);
                            if (records != null)
                            {
                                records.SaveToFile(fileName);
                                sbTask.處理進度 = StockSBDetailManager.SBTaskState.已抓取;
                            }
                            else
                            {
                                sbTask.處理進度 = StockSBDetailManager.SBTaskState.錯誤;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        sbTask.處理進度 = StockSBDetailManager.SBTaskState.錯誤;
                    }
                    sbTask.處理時間 = DateUtils.getYYYYMMDDHHSS(DateTime.Now);
                    StockSBDetailManager.updateTaskState(sbTask.taskId, sbTask.處理進度, DateTime.Now);
                }
                if (DateTime.Now.Subtract(preD).TotalSeconds > 1)
                {
                    dataGridView1.Refresh();
                    Application.DoEvents();
                    preD = DateTime.Now;
                }

            }
            /*****************************************************************************
             * 處理..
             * 
             * ****************************************************************************/

            sbDetailManager.preloadInst();

            foreach (StockSBDetailManager.SBRecordState sbTask in SBTasks)
            {
                if (sbTask.處理進度.Equals(StockSBDetailManager.SBTaskState.已抓取) == false)
                    continue;

                String fileName = path + sbTask.代號 + "_" + sbTask.taskId.ToString("B") + ".sb";
                SBRecords records = null;
                try
                {
                    records = SBRecords.LoadFromFile(fileName);
                    sbDetailManager.updateSBDetails(records.SBEntries, sbTask.taskId);
                    sbTask.處理進度 = StockSBDetailManager.SBTaskState.完成;
                    StockSBDetailManager.updateTaskState(sbTask.taskId, sbTask.處理進度, DateTime.Now);
                }
                catch (Exception e)
                {
                    sbTask.處理進度 = StockSBDetailManager.SBTaskState.錯誤;
                    StockSBDetailManager.updateTaskState(sbTask.taskId, sbTask.處理進度, DateTime.Now);
                }
                sbTask.處理時間 = DateUtils.getYYYYMMDDHHSS(DateTime.Now);
                if (DateTime.Now.Subtract(preD).TotalSeconds > 1)
                {
                    dataGridView1.Refresh();
                    Application.DoEvents();
                    preD = DateTime.Now;
                }
            }

        }
        private void button1_Click(object sender, EventArgs e)
        {

        }

        private void tabPage1_Click(object sender, EventArgs e)
        {

        }

        private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void button1_Click_1(object sender, EventArgs e)
        {



        }

        protected void LoadSBToPage2()
        {

        }
        /************************************************************************
         * 
         * 
         ************************************************************************/
        protected void InitSBConfig()
        {
            try
            {
                DateTime d = StockDataManager.getMaxTradeDate();
                sbDetailManager.prepareSBTask(d);
                SBTasks = sbDetailManager.getCurrentSBStates(d);
                dataGridView1.DataSource = SBTasks;
                dateTimePicker1.Value = DateUtils.getValidTradeDate(DateTime.Now);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "\r\n" + e.StackTrace);
            }
        }
        /************************************************************************
         * 
         * 
         ************************************************************************/
        private void Form1_Load(object sender, EventArgs e)
        {

        }
        /************************************************************************
         * 
         * 
         ************************************************************************/
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            startButton.Checked = true;
            stopButton.Checked = false;
            processSB();
        }

        private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0)
                return;
            try
            {
                String ss = SBTasks[e.RowIndex].代號 + "  " + SBTasks[e.RowIndex].名稱;
                stockStripLabel.Text = ss;

                DateTime d = StockDataManager.getMaxTradeDate();
                tabControl1.SelectedIndex = 1;
                //List<StockSBIE.StockSBDetailManager.SBDetial> ll = sbDetailManager.getSBDetails(SBTasks[e.RowIndex].代號, d);
                //dataGridView2.DataSource = ll;
                DataTable dt = sbDetailManager.getSBDetailsDataTable(SBTasks[e.RowIndex].代號, d);
                dataGridView2.DataSource = dt;


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void toolStripButton1_Click_1(object sender, EventArgs e)
        {
            int i = sbDetailManager.setErrorTaskToProcessWaiting();
            MessageBox.Show("總共重設:" + i + "筆");
            DateTime d = StockDataManager.getMaxTradeDate();
            SBTasks = sbDetailManager.getCurrentSBStates(d);
            dataGridView1.DataSource = SBTasks;

        }

        private void button1_Click_2(object sender, EventArgs e)
        {

        }

        StockDataManager manager = new StockDataManager();
        protected void processDailyIndex(DateTime d)
        {
            manager.preLoadCode();
            String url = String.Format("http://www.twse.com.tw/ch/trading/exchange/MI_INDEX/genpage/Report{0}/A112{1}ALLBUT0999_1.php?select2=ALLBUT0999&chk_date={2}", DateUtils.getYYYYMMPlanString(d), DateUtils.getPlanString(d), DateUtils.getROCString(d));
            String content = HttpGet.requestBig5(url);
            if (content.StartsWith("Error"))
            {
                MessageBox.Show(content);
                return;
            }
            DateTime realDate = DateTime.Now;
            List<List<String>> rows = StockIndexParser.processDailyTradeDataByHtml(content, ref realDate);
            if (rows == null)
                return;
            manager.preloadStockDaily(realDate);

            int rsz = rows.Count;
            progressBar1.Maximum = rsz;
            int ri = 0;
            foreach (List<String> row in rows)
            {
                if (row[0].Contains("證券"))
                    continue;
                manager.updateStockDaily(realDate, row, "tse");
                ri++;
                progressBar1.Value = ri;
                if (ri % 50 == 0)
                    Application.DoEvents();
            }


        }
        private void button1_Click_3(object sender, EventArgs e)
        {
            DateTime d = dateTimePicker1.Value;
            processDailyIndex(d);
            InitSBConfig();
        }

        private void InstConfigBtn_Click(object sender, EventArgs e)
        {
            InstManagerForm fm = new InstManagerForm();
            fm.Show();
        }
        MyStockDataContext context = new MyStockDataContext();
        private void button2_Click(object sender, EventArgs e)
        {
            context.ExecuteCommand("delete from insts");
            context.SubmitChanges();
            DbCommand cmd = SQLFactory.getInstance().getCommand("select * from insts");
            DbDataReader rdr = cmd.ExecuteReader();
            try
            {
                while (rdr.Read())
                {
                    Guid instId = rdr.GetGuid(0);
                    String instCode = rdr.GetString(1);
                    String instName = rdr.GetString(2);
                    String gids = rdr.GetValue(3).ToString();
                    Guid gid = Guid.Empty;
                    if ("".Equals(gids) == false)
                    {
                        gid = Guid.Parse(gids);
                    }
                    Inst inst = new Inst();
                    inst.InstId = instId;
                    inst.InstCode = instCode;
                    inst.InstName = instName;
                    if (gid.Equals(Guid.Empty) == false)
                        inst.InstGroupId = gid;
                    context.Insts.InsertOnSubmit(inst);
                }
                context.SubmitChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }
            rdr.Dispose();
            cmd.Dispose();
            //--------------> gid 
            try
            {


                context.ExecuteCommand("delete from instGroups");
                context.SubmitChanges();

                cmd = SQLFactory.getInstance().getCommand("select * from instGroups");
                rdr = cmd.ExecuteReader();
                while (rdr.Read())
                {
                    InstGroup ig = new InstGroup();
                    ig.instGroupId = rdr.GetGuid(0);
                    ig.集團名稱 = rdr.GetString(1);
                    ig.代表代號 = rdr.GetString(2);
                    context.InstGroups.InsertOnSubmit(ig);
                }
                context.SubmitChanges();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.StackTrace);
            }
            rdr.Dispose();
            cmd.Dispose();
        }

        private void button3_Click(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            context.ExecuteCommand("delete from StockDaily");
            context.SubmitChanges();
            DbCommand cmd = SQLFactory.getInstance().getCommand("select count(*) from StockDaily");
            int max = int.Parse(cmd.ExecuteScalar().ToString());
            progressBar2.Maximum = max;

            cmd.CommandText = "select * from StockDaily";

            DbDataReader rdr = cmd.ExecuteReader();
            int c = 0;
            while (rdr.Read())
            {
                c++;
                decimal tmpdec = new decimal(0);
                int tmpint = 0;
                StockDaily rec = new StockDaily();
                String ds = rdr.GetString(0);
                rec.日期 = DateTime.Parse(ds);
                rec.證券代號 = rdr.GetString(1);
                rec.成交股數 = rdr.GetInt32(2);
                rec.成交筆數 = rdr.GetInt32(3);
                if (decimal.TryParse(rdr.GetValue(4).ToString(), out tmpdec))
                    rec.成交金額 = tmpdec;
                if (decimal.TryParse(rdr.GetValue(5).ToString(), out tmpdec))
                    rec.開盤價 = tmpdec;//開

                if (decimal.TryParse(rdr.GetValue(6).ToString(), out tmpdec))
                    rec.最高價 = tmpdec;//高

                if (decimal.TryParse(rdr.GetValue(7).ToString(), out tmpdec))
                    rec.最低價 = tmpdec;//低
                if (decimal.TryParse(rdr.GetValue(8).ToString(), out tmpdec))
                    rec.收盤價 = tmpdec;//收

                rec.漲跌 = rdr.GetValue(9).ToString();//障跌

                if (decimal.TryParse(rdr.GetValue(10).ToString(), out tmpdec))
                    rec.漲跌價差 = tmpdec;



                if (decimal.TryParse(rdr.GetValue(11).ToString(), out tmpdec))
                    rec.最後揭示買價 = tmpdec;

                if (int.TryParse(rdr.GetValue(12).ToString(), out tmpint))
                    rec.最後揭示買量 = tmpint;

                if (decimal.TryParse(rdr.GetValue(13).ToString(), out tmpdec))
                    rec.最後揭示賣價 = tmpdec;

                if (int.TryParse(rdr.GetValue(14).ToString(), out tmpint))
                    rec.最後揭示賣量 = tmpint;

                if (decimal.TryParse(rdr.GetValue(15).ToString(), out tmpdec))
                    rec.本益比 = tmpdec;
                context.StockDailies.InsertOnSubmit(rec);
                if ((c % 100) == 0)
                    progressBar2.Value = c;
                Application.DoEvents();
            }
            context.SubmitChanges();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            context.ExecuteCommand("delete from SBDataTask");
            context.SubmitChanges();
            DbCommand cmd = SQLFactory.getInstance().getCommand("select count(*) from SBDataTask");
            int max = int.Parse(cmd.ExecuteScalar().ToString());
            progressBar2.Maximum = max;
            progressBar2.Value = 0;

            cmd.CommandText = "select * from SBDataTask";
            DbDataReader rdr = cmd.ExecuteReader();
            int c = 0;
            while (rdr.Read())
            {
                c++;
                SBDataTask task = new SBDataTask();
                String ds = rdr.GetString(0);
                task.日期 = DateTime.Parse(ds);
                task.StockCode = rdr.GetString(1);
                task.state = rdr.GetInt32(2);
                task.lastprocessTime = rdr.GetDateTime(3);
                task.SBId = rdr.GetGuid(4);
                context.SBDataTasks.InsertOnSubmit(task);

                if (c % 50 == 0)
                {
                    progressBar2.Value = c;
                    Application.DoEvents();
                }
            }
            context.SubmitChanges();
            rdr.Dispose();
            cmd.Dispose();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            context.ExecuteCommand("delete from SBDetails");
            context.SubmitChanges();
            DbCommand cmd = SQLFactory.getInstance().getCommand("select count(*) from SBDetails where taskId like '{%'");
            int max = int.Parse(cmd.ExecuteScalar().ToString());
            progressBar2.Maximum = max;
            progressBar2.Value = 0;

            cmd.CommandText = "select * from SBDetails where taskId like '{%'";
            DbDataReader rdr = cmd.ExecuteReader();
            int c = 0;


            DbTransaction transaction = SQLFactory.getInstance(0).BeginTransation();
            DbCommand cmd2 = SQLFactory.getInstance(0).getCommand();
            cmd2.Transaction = transaction;
            cmd2.CommandText = "Insert into SBDetails ( taskId,seq,instId,price,buy,sell) values (@taskId,@seq,@instId,@price,@buy,@sell )";
            DbParameter taskIdP = SQLFactory.getInstance(0).createParam("@taskId",DbType.Guid, null);
            DbParameter seqP = SQLFactory.getInstance(0).createParam("@seq", DbType.Int32, null);
            DbParameter instIdP = SQLFactory.getInstance(0).createParam("@instId", DbType.Guid, null);
            DbParameter priceP = SQLFactory.getInstance(0).createParam("@price", DbType.Decimal, null);
            DbParameter buyP = SQLFactory.getInstance(0).createParam("@buy", DbType.Int32, null);
            DbParameter sellP = SQLFactory.getInstance(0).createParam("@sell", DbType.Int32, null);

            cmd2.Parameters.Add(taskIdP);
            cmd2.Parameters.Add(seqP);
            cmd2.Parameters.Add(instIdP);
            cmd2.Parameters.Add(priceP);
            cmd2.Parameters.Add(buyP);
            cmd2.Parameters.Add(sellP);

            

            while (rdr.Read())
            {
                c++;
                cmd2.Parameters[0].Value = rdr.GetGuid(0).ToString("B");
                cmd2.Parameters[1].Value = rdr.GetInt32(1);
                cmd2.Parameters[2].Value = rdr.GetGuid(2).ToString("B");
                cmd2.Parameters[3].Value = rdr.GetDecimal(3);
                cmd2.Parameters[4].Value = rdr.GetInt32(4);
                cmd2.Parameters[5].Value = rdr.GetInt32(5);
                cmd2.ExecuteNonQuery();
                if ((c % 50) == 0)
                {
                    progressBar2.Value = c;
                    Application.DoEvents();
                }
            }
            transaction.Commit();
            cmd2.Dispose();
        }

        private void button7_Click(object sender, EventArgs e)
        {
            //修正..
            List<SBDataTask> tasks=(from task  in context.SBDataTasks select task).ToList<SBDataTask>();

            progressBar2.Maximum = tasks.Count;
            progressBar2.Value = 0;

            //DbTransaction transaction = SQLFactory.getInstance(0).BeginTransation();
            DbCommand cmd2 = SQLFactory.getInstance(0).getCommand();
            //cmd2.Transaction = transaction;
            cmd2.CommandText = "update SBDetails set 日期=@date, StockCode=@stockCode where taskId=@taskId";
            DbParameter dateP = SQLFactory.getInstance(0).createParam("@date", DbType.Date, null);
            DbParameter stockcodeP = SQLFactory.getInstance(0).createParam("@stockCode", DbType.String, null);
            DbParameter IdP = SQLFactory.getInstance(0).createParam("@taskId", DbType.Guid, null);
            cmd2.Parameters.Add(dateP);
            cmd2.Parameters.Add(stockcodeP);
            cmd2.Parameters.Add(IdP);

            int c = 0;
            int cc = 0;
            foreach (SBDataTask t in tasks)
            {
                
                dateP.Value = t.日期;
                stockcodeP.Value = t.StockCode;
                IdP.Value = t.SBId.ToString("B");
                cc=cmd2.ExecuteNonQuery();
                c++;
                if (c % 10 == 0)
                {
                    progressBar2.Value = c;
                    Application.DoEvents();
                }
            }

        }
    }
}
